package main

import (
	"fmt"
	"log"

	"github.com/lxn/walk"
	. "github.com/lxn/walk/declarative"
)

var (
	backgroundColor = walk.RGB(230, 230, 230)
	pointColor      = walk.RGB(0, 0, 0)
	pointWidth      = 5
)

func NewMyMainWindow() *MyMainWindow {
	return new(MyMainWindow)
}

//初始化窗体
func (this *MyMainWindow) init(x, y, w, h int) error {
	this.grid = NewGrids(w, h)
	log.Println("初始化窗体")
	dmw := MainWindow{
		AssignTo:  &this.MainWindow,
		Title:     "学习",
		Layout:    VBox{MarginsZero: true},
		Maximize:  true,
		Minimize:  true,
		FixedSize: true,
		Children: []Widget{
			CustomWidget{
				AssignTo:            &this.paintWidget,
				ClearsBackground:    true,
				InvalidatesOnResize: true,
				Paint:               this.paintInit,
			},
			//PushButton{},
		},
	}
	dmw.Create()
	if ic, err := walk.NewIconFromFile("icon.ico"); err != nil {
		return err
	} else {
		this.MainWindow.SetIcon(ic)
	}
	//窗体位置宽高
	if err := this.MainWindow.SetBounds(walk.Rectangle{x, y, w + 20, h + 40}); err != nil {
		return err
	}
	//剧中
	bounds := this.paintWidget.ClientBounds()
	x = (bounds.Width - this.grid.Cols) / 2
	y = (bounds.Height - this.grid.Rows) / 2
	if err := this.paintWidget.SetBounds(walk.Rectangle{X: x, Y: y, Width: this.grid.Cols, Height: this.grid.Rows}); err != nil {
		return err
	}
	//log.Println(this.grid.Cols, this.grid.Rows, bounds.Width, bounds.Height, x, y)
	return nil
}

//设置起始点
func (this *MyMainWindow) setStartPoint(x, y int) {
	this.startX = x
	this.startY = y
}

//设置结束点
func (this *MyMainWindow) setEndPoint(x, y int) {
	this.endX = x
	this.endY = y
}

//Paint
func (this *MyMainWindow) paintInit(c *walk.Canvas, updateBounds walk.Rectangle) error {
	err := this.canvasInit()
	if err != nil {
		return err
	}
	//注册事件
	this.regEvents()
	return nil
}

//画背景
func (this *MyMainWindow) drawBackground() error {
	log.Println("初始化背景")
	bounds := this.paintWidget.ClientBounds()
	//画背景
	backgroundBrush, err := walk.NewSolidColorBrush(backgroundColor)
	if err != nil {
		return err
	}
	defer backgroundBrush.Dispose()
	if err := this.canvas.FillRectangle(backgroundBrush, bounds); err != nil {
		return err
	}
	//初始化起始点
	if err = this.startPoint(this.startX, this.startY); err != nil {
		return err
	}
	if err = this.endPoint(this.endX, this.endY); err != nil {
		return err
	}
	return nil
}

//画布初始化
func (this *MyMainWindow) canvasInit() error {
	log.Println("初始化画布")
	canvas, err := this.paintWidget.CreateCanvas()
	if err != nil {
		return err
	}
	//得到画布
	this.canvas = canvas
	//画背景
	return this.drawBackground()
}

//设置起始点
func (this *MyMainWindow) startPoint(x, y int) error {
	var form, to walk.Point
	var body Body
	var err error
	//起始点移除
	body = Body{color: backgroundColor, style: walk.PenSolid, width: pointWidth}
	form = walk.Point{this.grid.Start.X, this.grid.Start.Y}
	to = walk.Point{this.grid.Start.X, this.grid.Start.Y}
	err = this.drawLine(form, to, body)
	if err != nil {
		log.Println(err)
		return err
	}
	//设置起始点
	this.grid.Start = this.grid.Node(x, y)
	//画结起始点
	body = Body{color: walk.RGB(0, 129, 2), style: walk.PenSolid, width: pointWidth}
	form = walk.Point{this.grid.Start.X, this.grid.Start.Y}
	to = walk.Point{this.grid.Start.X, this.grid.Start.Y}
	err = this.drawLine(form, to, body)
	if err != nil {
		log.Println(err)
		return err
	}
	return nil
}

//设置结束点
func (this *MyMainWindow) endPoint(x, y int) error {
	var form, to walk.Point
	var body Body
	var err error
	//设置之前将之前的结束点移除
	body = Body{color: backgroundColor, style: walk.PenSolid, width: pointWidth}
	form = walk.Point{this.grid.End.X, this.grid.End.Y}
	to = walk.Point{this.grid.End.X, this.grid.End.Y}
	err = this.drawLine(form, to, body)
	if err != nil {
		log.Println(err)
		return err
	}
	//设置结束点
	this.grid.End = this.grid.Node(x, y)
	//画结束点
	body = Body{color: pointColor, style: walk.PenSolid, width: pointWidth}
	form = walk.Point{this.grid.End.X, this.grid.End.Y}
	to = walk.Point{this.grid.End.X, this.grid.End.Y}
	err = this.drawLine(form, to, body)
	if err != nil {
		log.Println(err)
		return err
	}
	return nil
}

//画椭圆
func (this *MyMainWindow) drawEllipse(rectangle walk.Rectangle, body Body) error {
	brush, err := walk.NewSolidColorBrush(body.color)
	if err != nil {
		return err
	}
	defer brush.Dispose()
	//walk.PenDash
	pen, err := walk.NewGeometricPen(body.style, body.width, brush)
	if err != nil {
		return err
	}
	defer pen.Dispose()
	if err := this.canvas.DrawEllipse(pen, rectangle); err != nil {
		return err
	}
	return nil
}

//画线
func (this *MyMainWindow) drawLine(form, to walk.Point, body Body) error {
	brush, err := walk.NewSolidColorBrush(body.color)
	if err != nil {
		return err
	}
	defer brush.Dispose()
	linesPen, err := walk.NewGeometricPen(body.style, body.width, brush)
	if err != nil {
		return err
	}
	defer linesPen.Dispose()
	if err := this.canvas.DrawLine(linesPen, form, to); err != nil {
		return err
	}
	return nil
}

//画文字
func (this *MyMainWindow) drawText(rectangle walk.Rectangle) error {
	textBody := this.textBody
	font, err := walk.NewFont(textBody.family, textBody.pointSize, textBody.style)
	if err != nil {
		return err
	}
	defer font.Dispose()
	if err = this.canvas.DrawText("s", font, textBody.color, rectangle, textBody.textFormat); err != nil {
		return err
	}

	font, err = walk.NewFont(textBody.family, textBody.pointSize, textBody.style)
	if err != nil {
		return err
	}
	defer font.Dispose()
	if err = this.canvas.DrawText(" ", font, textBody.color, rectangle, textBody.textFormat); err != nil {
		return err
	}
	return nil
}

//注册事件
func (this *MyMainWindow) regEvents() {
	log.Println("注册事件")
	//鼠标点击事件
	this.paintWidget.MouseDown().Attach(func(x, y int, button walk.MouseButton) {
		this.endPoint(x, y)
	})
	this.textBody = &TextBody{family: "", pointSize: 10, style: walk.FontUnderline, textFormat: walk.TextCenter, color: walk.RGB(0, 0, 0)}
	//鼠标移动事件
	this.paintWidget.MouseMove().Attach(func(x, y int, button walk.MouseButton) {
		//this.endPoint(x, y)
		rectangle := walk.Rectangle{x, y, 50, 30}
		this.textBody.text = fmt.Sprint(x, y)
		this.drawText(rectangle)
	})
	this.calculate()
}

//计算 开始寻路
func (this *MyMainWindow) calculate() {
	//开始寻路
	searchPath(this)
}

//运行
func (this *MyMainWindow) run() int {
	return this.MainWindow.Run()
}
